import socket
import time
import struct

VER = '1.0'

class DataStream:
    def __init__(self, data: bytes, pktsize: int) -> None:
        self.data = data
        self.length = len(data)
        self.readptr = 0
        self.pktsize = pktsize
        self.amount = self.length // self.pktsize + 1
        pass

    def __iter__(self):
        return self

    def __next__(self):
        if self.readptr < self.length:
            nxtptr = self.readptr + min(self.pktsize, self.length - self.readptr)
            tmpdata = self.data[self.readptr : nxtptr]
            self.readptr = nxtptr
            return tmpdata
        elif self.readptr == self.length:
            self.readptr += 1
            print('void sent')
            return b''
        else:
            print('stopped')
            raise StopIteration

    pass


class RDT10Client:
    def __init__(self, filename: str, pktsize: int, target: tuple[str, int]) -> None:
        self.datastream = DataStream(open(filename, "rb").read(), pktsize)
        self.pktsize = pktsize
        self.target = target
        self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        pass

    def makepkt(self, rawdata: bytes):
        # rdt 1.0 报文格式: 无报文头
        return struct.pack("!%ds" % len(rawdata), rawdata)
    
    def sendpkt(self, pkt: bytes):
        self.clientSocket.sendto(pkt, self.target)

    def run(self):
        # 发送频率过快,发送队列满导致丢包(没发出去)
        # https://www.cnblogs.com/liaokang/p/6003334.html

        dataiter = iter(self.datastream)

        while True:
            try:
                i = next(dataiter)
                print('at ', self.datastream.readptr)
                self.sendpkt(self.makepkt(i))
            except StopIteration:
                break

    # def run(self):
    #     # 发送频率过快,发送队列满导致丢包(没发出去)
    #     # https://www.cnblogs.com/liaokang/p/6003334.html
    #     for i in self.datastream:
    #         # 加个print就可以正常发送并完全接受
    #         print('at ', self.datastream.readptr)
    #         self.sendpkt(self.makepkt(i))
    #         # time.sleep(0.0000000000001)
    #     pass

    pass

c = RDT10Client('komeiji.png', 960, ('127.0.0.1', 65432))
c.run()